package org.example.handler;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.stomp.*;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import org.example.listener.RedisPublisher;
import org.example.listener.RedisSubscriber;

import java.io.IOException;

public class Netty4StompWebSocketFrameHandler extends SimpleChannelInboundHandler<StompFrame> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, StompFrame stompFrame) {
        // 从 ctx 中读取用户 ID
        String userId = ctx.channel().attr(CustomAttributes.USER_ID).get();
        System.out.println("User ID: " + userId);

        String command = stompFrame.command().name();
        System.out.println("Received STOMP command: " + command);

        handleStompCommand(ctx, stompFrame);
    }
    private void handleStompCommand(ChannelHandlerContext ctx, StompFrame frame) {
        StompCommand command = frame.command();
        switch (command) {
            case CONNECT:
                handleConnect(ctx, frame);
                break;
            case SUBSCRIBE:
                handleSubscribe(ctx, frame);
                break;
            case SEND:
                handleSendMessage(ctx, frame);
                break;
            case DISCONNECT:
                handleDisconnect(ctx, frame);
                break;
            default:
                ctx.fireChannelRead(frame);
        }
    }

    private void handleConnect(ChannelHandlerContext ctx, StompFrame frame) {
        // 创建一个 CONNECTED 响应消息
        StompHeaders headers = new DefaultStompHeaders();
        headers.set(StompHeaders.VERSION, "1.2");
        headers.set(StompHeaders.DESTINATION, "/topic/chat");
        headers.set(StompHeaders.CONTENT_TYPE, "text/plain");

        // 创建带有内容的 STOMP 帧
        DefaultStompFrame stompFrame = new DefaultStompFrame(StompCommand.CONNECTED);
        stompFrame.headers().set(headers);

        // 添加消息内容
        stompFrame.content().writeBytes(Unpooled.copiedBuffer("Hello STOMP!", CharsetUtil.UTF_8));

        // 发送带内容的 STOMP 帧
        ctx.writeAndFlush(stompFrame);
    }

    private void handleSubscribe(ChannelHandlerContext ctx, StompFrame frame) {
        // 处理订阅的逻辑
        String destination = frame.headers().getAsString(StompHeaders.DESTINATION);
        RedisSubscriber.subscribeToChannel(destination, ctx.channel());
    }

    private void handleSendMessage(ChannelHandlerContext ctx, StompFrame frame) {

        // 处理点对点、一对多、群消息
        String destination = frame.headers().getAsString(StompHeaders.DESTINATION);
        String messageBody = frame.content().toString(CharsetUtil.UTF_8);
        RedisPublisher.publishMessage(destination, messageBody);
    }

    private void handleDisconnect(ChannelHandlerContext ctx, StompFrame frame) {
        // 处理断开连接
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 假设我们获取到了用户 ID（例如从登录信息中获取）
        String userId = "user123";
        // 将用户 ID 存入 ctx 中
        ctx.channel().attr(CustomAttributes.USER_ID).set(userId);
        // 继续调用其他 handlers
        ctx.fireChannelActive();
    }

    // 当 WebSocket 客户端连接关闭时，关闭 Channel
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("Client disconnected: " + ctx.channel().id());
        ctx.close();
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("Connection closed by client: " + ctx.channel().remoteAddress());
        // 处理连接关闭，例如移除用户的会话信息
        //UserSessionManager.removeUser(ctx.channel().id().asLongText());
        ctx.close();
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                System.out.println("No data received for a while, closing connection.");
                ctx.close();  // 主动关闭空闲连接
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        System.err.println("Connection error: " + cause.getMessage());
        // 根据具体的异常类型进行处理，处理连接关闭或其他错误
        if (cause instanceof IOException) {
            System.err.println("Network IO error: " + cause.getMessage());
        } else {
            System.err.println("Other error: " + cause.getMessage());
        }
        ctx.close();
    }
}
